home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 19 / CU Amiga Magazine's Super CD-ROM 19 (1998)(EMAP Images)(GB)[!][issue 1998-02].iso / CUCD / Programming / LEDA / source / src / dict / _avl_tree.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-11-16  |  3.3 KB  |  168 lines

  1. /*******************************************************************************
  2. +
  3. +  LEDA  3.1c
  4. +
  5. +
  6. +  _avl_tree.c
  7. +
  8. +
  9. +  Copyright (c) 1994  by  Max-Planck-Institut fuer Informatik
  10. +  Im Stadtwald, 6600 Saarbruecken, FRG     
  11. +  All rights reserved.
  12. *******************************************************************************/
  13.  
  14.  
  15. #include <LEDA/impl/avl_tree.h>
  16.  
  17.  
  18. //----------------------------------------------------------------------------
  19. //  avl_tree:
  20. //
  21. //  rebalancing routines for AVL trees
  22. //
  23. //----------------------------------------------------------------------------
  24.  
  25.  
  26. void avl_tree::insert_rebal(avl_tree_item v)
  27. {
  28.   // preconditions:  v is new node created by insertion
  29.   //                 v != root
  30.   //                 height(v) == 1, bal(v) == 0;
  31.  
  32.   // bal(v) == height(R) - height(L)           
  33.  
  34.   //                    u
  35.   //                    |
  36.   //                    v
  37.   //                   / \
  38.   //                  L   R
  39.   //
  40.  
  41.   
  42.   while ( v != root() )
  43.   {
  44.     avl_tree_item u = v->parent;
  45.  
  46.     int dir = (v == u->child[left]) ? left : right;
  47.  
  48.     int b = u->get_bal();
  49.  
  50.     if (dir==left)   // insertion in left subtree of u 
  51.        b--;
  52.     else             // insertion in right subtree of u
  53.        b++; 
  54.  
  55.     u->set_bal(b);
  56.  
  57.     if (b==0)  break;   // height of u has not changed 
  58.  
  59.     if (b != 1 && b != -1)
  60.     { 
  61.       // u is out of balance (-2 or + 2)
  62.  
  63.       int d = (b < 0) ? -1 : +1;
  64.   
  65.       avl_tree_item w = u->child[dir];
  66.   
  67.       if (w->get_bal() == d)
  68.       { rotation(u,w,dir);
  69.         u->set_bal(0);
  70.         w->set_bal(0);
  71.        }
  72.       else
  73.       { avl_tree_item x = w->child[1-dir];
  74.         double_rotation(u,w,x,dir);
  75.  
  76.         if (x->get_bal() == d)
  77.            u->set_bal(-d);
  78.         else
  79.            u->set_bal(0);
  80.   
  81.         if (x->get_bal() == -d)
  82.            w->set_bal(d);
  83.         else
  84.            w->set_bal(0);
  85.   
  86.         x->set_bal(0);
  87.        }
  88.   
  89.       break;
  90.     }
  91.  
  92.     v = u;
  93.  
  94.   }
  95.  
  96. }
  97.  
  98.  
  99. void avl_tree::del_rebal(avl_tree_item v, avl_tree_item)
  100. {
  101.   // precondition:    p is removed inner node
  102.   //                  v is remaining child of p (already linked to parent u)
  103.   //                  v != root
  104.  
  105.   
  106.   while ( v != root() )
  107.   {
  108.     avl_tree_item u = v->parent;
  109.  
  110.     int dir = (v == u->child[left]) ? left : right;
  111.  
  112.     int b = u->get_bal();
  113.  
  114.     if (dir==left)  // deletion in left  subtree of u
  115.        b++;
  116.     else            // deletion in right subtree of u
  117.        b--;
  118.  
  119.     u->set_bal(b);
  120.  
  121.     if (b == 1 || b == -1) break;   // height of u has not changed
  122.  
  123.     if (b != 0)
  124.     { 
  125.       // u is out of balance (-2 or + 2)
  126.  
  127.       int d = (b < 0) ? -1 : +1;
  128.   
  129.       avl_tree_item w = u->child[1-dir];
  130.   
  131.       if (d * w->get_bal() >= 0)
  132.       { rotation(u,w,1-dir);
  133.         if (w->get_bal() == 0)
  134.           { u->set_bal(d);
  135.             w->set_bal(-d);
  136.             break;
  137.            }
  138.         else
  139.           { u->set_bal(0);
  140.             w->set_bal(0);
  141.            }
  142.         v = w;
  143.        }
  144.       else
  145.       { avl_tree_item x = w->child[dir];
  146.         double_rotation(u,w,x,1-dir);
  147.  
  148.         if (x->get_bal() == d)
  149.            u->set_bal(-d);
  150.         else
  151.            u->set_bal(0);
  152.   
  153.         if (x->get_bal() == -d)
  154.            w->set_bal(d);
  155.         else
  156.            w->set_bal(0);
  157.   
  158.         x->set_bal(0);
  159.         v = x;
  160.        }
  161.     }
  162.  
  163.     else v = u;
  164.  
  165.   }
  166. }
  167.